In [1]:
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import warnings
excel_file = r"C:\Users\benor\Desktop\SuperStoreUS-2015.xlsx"
df = pd.read_excel(excel_file)
csv_file = r"C:\Users\benor\Desktop\SuperStoreUS-2015.csv"
df.to_csv(csv_file, index=False, encoding="utf-8")
print(f"CSV dosyası başarıyla kaydedildi: {csv_file}")
df.replace([np.inf, -np.inf], np.nan, inplace=True)
warnings.simplefilter(action='ignore', category=FutureWarning)
CSV dosyası başarıyla kaydedildi: C:\Users\benor\Desktop\SuperStoreUS-2015.csv
In [2]:
df.head()
Out[2]:
Row ID Order Priority Discount Unit Price Shipping Cost Customer ID Customer Name Ship Mode Customer Segment Product Category ... Region State or Province City Postal Code Order Date Ship Date Profit Quantity ordered new Sales Order ID
0 20847 High 0.01 2.84 0.93 3 Bonnie Potter Express Air Corporate Office Supplies ... West Washington Anacortes 98221 2015-01-07 2015-01-08 4.5600 4 13.01 88522
1 20228 Not Specified 0.02 500.98 26.00 5 Ronnie Proctor Delivery Truck Home Office Furniture ... West California San Gabriel 91776 2015-06-13 2015-06-15 4390.3665 12 6362.85 90193
2 21776 Critical 0.06 9.48 7.29 11 Marcus Dunlap Regular Air Home Office Furniture ... East New Jersey Roselle 7203 2015-02-15 2015-02-17 -53.8096 22 211.15 90192
3 24844 Medium 0.09 78.69 19.99 14 Gwendolyn F Tyson Regular Air Small Business Furniture ... Central Minnesota Prior Lake 55372 2015-05-12 2015-05-14 803.4705 16 1164.45 86838
4 24846 Medium 0.08 3.28 2.31 14 Gwendolyn F Tyson Regular Air Small Business Office Supplies ... Central Minnesota Prior Lake 55372 2015-05-12 2015-05-13 -24.0300 7 22.23 86838

5 rows × 25 columns

In [3]:
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1952 entries, 0 to 1951
Data columns (total 25 columns):
 #   Column                Non-Null Count  Dtype         
---  ------                --------------  -----         
 0   Row ID                1952 non-null   int64         
 1   Order Priority        1952 non-null   object        
 2   Discount              1952 non-null   float64       
 3   Unit Price            1952 non-null   float64       
 4   Shipping Cost         1952 non-null   float64       
 5   Customer ID           1952 non-null   int64         
 6   Customer Name         1952 non-null   object        
 7   Ship Mode             1952 non-null   object        
 8   Customer Segment      1952 non-null   object        
 9   Product Category      1952 non-null   object        
 10  Product Sub-Category  1952 non-null   object        
 11  Product Container     1952 non-null   object        
 12  Product Name          1952 non-null   object        
 13  Product Base Margin   1936 non-null   float64       
 14  Country               1952 non-null   object        
 15  Region                1952 non-null   object        
 16  State or Province     1952 non-null   object        
 17  City                  1952 non-null   object        
 18  Postal Code           1952 non-null   int64         
 19  Order Date            1952 non-null   datetime64[ns]
 20  Ship Date             1952 non-null   datetime64[ns]
 21  Profit                1952 non-null   float64       
 22  Quantity ordered new  1952 non-null   int64         
 23  Sales                 1952 non-null   float64       
 24  Order ID              1952 non-null   int64         
dtypes: datetime64[ns](2), float64(6), int64(5), object(12)
memory usage: 381.4+ KB
In [4]:
columns_to_drop = [
    'Row ID', 'Customer ID', 'Customer Name',
    'Product Container',
     'Order Priority', 'Ship Mode',
    'Ship Date', 'Postal Code', 'Country'
]

df = df.drop(columns=columns_to_drop)
In [5]:
df.isnull().sum()
Out[5]:
Discount                 0
Unit Price               0
Shipping Cost            0
Customer Segment         0
Product Category         0
Product Sub-Category     0
Product Name             0
Product Base Margin     16
Region                   0
State or Province        0
City                     0
Order Date               0
Profit                   0
Quantity ordered new     0
Sales                    0
Order ID                 0
dtype: int64
In [6]:
df = df.dropna(subset=["Product Base Margin"])
In [7]:
df.shape
Out[7]:
(1936, 16)

📊 Kategori Bazlı Performans Analizi¶


Amaç¶

Bu analizde, ürünlerin ait oldukları kategori bazında satış hacmi, toplam kâr, satış miktarı, kârlılık oranı ve ortalama indirim oranı gibi temel metrikler değerlendirilmiştir. Bu sayede her bir kategorinin iş performansı çok boyutlu olarak karşılaştırılmış, indirim stratejilerinin kâr üzerindeki etkisi de ayrıca analiz edilmiştir. Elde edilen bulgular, daha verimli ürün gruplarının belirlenmesine ve portföy yönetiminin bu doğrultuda optimize edilmesine katkı sağlamaktadır.

Uygulanan Analizler¶

  • Toplam satışlara göre kategori sıralaması
  • Toplam kâra göre kategori sıralaması
  • Satış miktarına (adet bazında) göre kategori karşılaştırması
  • Kârlılık oranına göre (kâr / satış) analiz ve karşılaştırma
  • Kategori bazında indirim ve kar ilişkisi
In [8]:
category_analysis = df.groupby(["Product Category"]).agg(
    Total_Sales=("Sales", "sum"),
    Total_Profit=("Profit", "sum"),
    Quantity_Sold=("Quantity ordered new", "sum")
).reset_index()

category_analysis.head()  
Out[8]:
Product Category Total_Sales Total_Profit Quantity_Sold
0 Furniture 619578.75 49515.527436 4912
1 Office Supplies 549681.07 90204.715937 14272
2 Technology 712264.95 75303.156364 5918
In [9]:
category_analysis = category_analysis.sort_values(by="Total_Sales", ascending=False)

plt.figure(figsize=(10,5))
plt.bar(category_analysis["Product Category"], category_analysis["Total_Sales"], color='blue')
plt.xlabel("Ürün Kategorisi")
plt.ylabel("Toplam Satış ($)")
plt.title("Kategori Bazında Satış Dağılımı")
plt.xticks(rotation=45)
plt.show()
No description has been provided for this image
In [10]:
category_analysis = category_analysis.sort_values(by="Total_Profit", ascending=False)


plt.figure(figsize=(10,5))
plt.bar(category_analysis["Product Category"], category_analysis["Total_Profit"], color='green')
plt.xlabel("Ürün Kategorisi")
plt.ylabel("Toplam Kâr ($)")
plt.title("Kategori Bazında Kâr Dağılımı")
plt.xticks(rotation=45)
plt.show()
No description has been provided for this image
In [11]:
category_analysis = category_analysis.sort_values(by="Quantity_Sold", ascending=False)

# Bar grafiği çizdirme
plt.figure(figsize=(10,5))
plt.bar(category_analysis["Product Category"], category_analysis["Quantity_Sold"], color='orange')
plt.xlabel("Ürün Kategorisi")
plt.ylabel("Satılan Ürün Adedi")
plt.title("Kategori Bazında Satış Miktarı")
plt.xticks(rotation=45)
plt.show()
No description has been provided for this image
In [12]:
category_analysis["Profit Margin (%)"] = (category_analysis["Total_Profit"] / category_analysis["Total_Sales"]) * 100

category_analysis = category_analysis.sort_values(by="Profit Margin (%)", ascending=False)

plt.figure(figsize=(10,5))
plt.bar(category_analysis["Product Category"], category_analysis["Profit Margin (%)"], color='purple')
plt.xlabel("Ürün Kategorisi")
plt.ylabel("Kârlılık Oranı (%)")
plt.title("Kategori Bazında Kârlılık Oranı")
plt.xticks(rotation=45)
plt.show()
No description has been provided for this image
In [13]:
category_analysis = df.groupby("Product Category").agg({
    "Sales": "sum",
    "Profit": "sum",
    "Discount": "mean"
}).reset_index()

category_analysis.columns = ["Product Category", "Total_Sales", "Total_Profit", "Discount"]
plt.figure(figsize=(10, 6))
plt.scatter(
    category_analysis["Discount"],
    category_analysis["Total_Profit"],
    color=["blue", "green", "red"],
    s=200
)


for i in range(len(category_analysis)):
    plt.annotate(
        category_analysis["Product Category"][i],
        (category_analysis["Discount"][i], category_analysis["Total_Profit"][i]),
        textcoords="offset points",
        xytext=(0, 10),
        ha='center',
        fontsize=10
    )


plt.xlim(0.045, 0.051)  
plt.xlabel("Ortalama İndirim Oranı (%)")
plt.ylabel("Toplam Kâr ($)")
plt.title("Kategori Bazında İndirim ve Kâr İlişkisi")
plt.grid(True)
plt.tight_layout()
plt.show()
No description has been provided for this image

🔍 Analiz Sonuçları ve Gözlemler

  • Office Supplies kategorisi, en yüksek satış adedi ve kârlılık oranına sahiptir.

  • Technology kategorisi, en yüksek toplam satış değerine ulaşmıştır.

  • Furniture kategorisi, düşük kârlılık oranı ve toplam kâr ile diğer kategorilerin gerisinde kalmıştır.

  • İndirim oranı en yüksek olan kategori Office Supplies’tır; bu kategori aynı zamanda en yüksek kârı sağlamıştır.

  • İndirim ve kâr ilişkisi, kategoriler arasında belirgin farklılıklar göstermektedir.


📊 ABC Analizi ile Ürün Portföyünü Optimize Etme¶


🎯 Amaç¶

Bu analiz, ürün portföyünün satış hacmine göre stratejik olarak sınıflandırılarak kaynakların daha etkin yönetilmesini sağlamak amacıyla gerçekleştirilmiştir.
Satış, kâr, stok miktarı ve zarar gibi metrikler üzerinden yapılan ABC sınıflandırması ile yüksek öneme sahip ürünlerin tespiti ve stok yönetimi hedeflenmiştir.

📊 Uygulanan Analizler¶

  • ABC Kategorilerinin Oluşturulması
  • ABC Kategorilerine Göre Ürün Sayısı
  • ABC Kategorilerine Göre Satış Dağılımı
  • ABC Kategorilerine Göre Toplam Stok Miktarı
  • ABC Kategorilerine Göre Toplam Kâr
  • Ortalama Kâr Marjı Analizi (ABC Bazlı)
  • A Kategorisinde Zarar Ettiren Ürünler
In [14]:
product_sales = df.groupby("Product Name")["Sales"].sum().reset_index()

product_sales = product_sales.sort_values(by="Sales", ascending=False)

total_sales = product_sales["Sales"].sum()

product_sales["Cumulative Sales"] = product_sales["Sales"].cumsum()
product_sales["Cumulative Percentage"] = product_sales["Cumulative Sales"] / total_sales * 100

def abc_category(percentage):
    if percentage <= 70:
        return "A"
    elif percentage <= 90:
        return "B"
    else:
        return "C"
product_sales["ABC Category"] = product_sales["Cumulative Percentage"].apply(abc_category)

df = df.merge(product_sales[["Product Name", "ABC Category"]], on="Product Name", how="left")

df.head()
Out[14]:
Discount Unit Price Shipping Cost Customer Segment Product Category Product Sub-Category Product Name Product Base Margin Region State or Province City Order Date Profit Quantity ordered new Sales Order ID ABC Category
0 0.01 2.84 0.93 Corporate Office Supplies Pens & Art Supplies SANFORD Liquid Accent™ Tank-Style Highlighters 0.54 West Washington Anacortes 2015-01-07 4.5600 4 13.01 88522 C
1 0.02 500.98 26.00 Home Office Furniture Chairs & Chairmats Global Troy™ Executive Leather Low-Back Tilter 0.60 West California San Gabriel 2015-06-13 4390.3665 12 6362.85 90193 A
2 0.06 9.48 7.29 Home Office Furniture Office Furnishings DAX Two-Tone Rosewood/Black Document Frame, De... 0.45 East New Jersey Roselle 2015-02-15 -53.8096 22 211.15 90192 C
3 0.09 78.69 19.99 Small Business Furniture Office Furnishings Howard Miller 12-3/4 Diameter Accuwave DS ™ Wa... 0.43 Central Minnesota Prior Lake 2015-05-12 803.4705 16 1164.45 86838 B
4 0.08 3.28 2.31 Small Business Office Supplies Pens & Art Supplies Newell 321 0.56 Central Minnesota Prior Lake 2015-05-12 -24.0300 7 22.23 86838 C
In [15]:
plt.figure(figsize=(8, 5))

sns.set_style("whitegrid")
colors = ["#B0E0FF", "#64A5FC", "#1976D2"]  # Açık-Orta-Koyu mavi

bar = sns.countplot(
    x="ABC Category",
    data=product_sales,
    palette=colors
)

for i in bar.containers:
    bar.bar_label(i, fmt='%d', label_type='edge', padding=2, fontsize=10, weight='bold')

plt.title("ABC Kategorilerine Göre Ürün Sayısı", fontsize=14, fontweight="bold")
plt.xlabel("ABC Kategorisi", fontsize=12)
plt.ylabel("Ürün Sayısı", fontsize=12)

plt.xticks(fontsize=11)
plt.yticks(fontsize=11)
plt.tight_layout()
plt.show()
No description has been provided for this image
In [16]:
abc_sales = product_sales.groupby("ABC Category")["Sales"].sum()

abc_sales = abc_sales.reindex(["A", "B", "C"])

colors = ["#B0E0FF", "#64A5FC", "#1976D2"] 


def label_format(pct, allvals):
    absolute = int(round(pct / 100. * sum(allvals)))
    return f"{pct:.1f}%\n(${absolute:,})"

explode = [0.08, 0.02, 0.02]

plt.figure(figsize=(8, 6))
plt.pie(
    abc_sales,
    labels=abc_sales.index,
    autopct=lambda pct: label_format(pct, abc_sales),
    colors=colors,
    startangle=90,
    explode=explode,
    shadow=True,
    wedgeprops={"edgecolor": "black"}
)

plt.title("ABC Kategorilerine Göre Satış Dağılımı", fontsize=14, fontweight="bold")
plt.axis("equal") 
plt.tight_layout()
plt.show()
No description has been provided for this image
In [17]:
stock_by_abc = df.groupby("ABC Category")["Quantity ordered new"].sum().reset_index()
In [18]:
plt.figure(figsize=(8, 6))
sns.set_style("whitegrid")

bar = sns.barplot(
    x="ABC Category",
    y="Quantity ordered new",
    data=stock_by_abc,
    palette="crest"
)

for i in bar.containers:
    bar.bar_label(i, fmt='%.0f', label_type='edge', fontsize=10, padding=3)

plt.title("ABC Kategorilerine Göre Toplam Stok Miktarı", fontsize=14, fontweight='bold')
plt.xlabel("ABC Kategorisi", fontsize=12)
plt.ylabel("Toplam Stok Miktarı", fontsize=12)

plt.xticks(fontsize=11)
plt.yticks(fontsize=11)
plt.tight_layout()
plt.show()
No description has been provided for this image
In [19]:
fig, ax1 = plt.subplots(figsize=(8, 5))
profit_by_abc = df.groupby("ABC Category")["Profit"].sum().reset_index()

lineplot = sns.lineplot(
    x=profit_by_abc["ABC Category"],
    y=profit_by_abc["Profit"],
    marker="o",
    color="red",
    label="Kâr",
    ax=ax1
)
ax1.set_ylabel("Toplam Kâr ($)", color="red")
ax1.tick_params(axis='y', labelcolor="red")

ax2 = ax1.twinx()
barplot = sns.barplot(
    x=stock_by_abc["ABC Category"],
    y=stock_by_abc["Quantity ordered new"],
    alpha=0.5,
    color="blue",
    label="Stok Miktarı",
    ax=ax2
)
ax2.set_ylabel("Toplam Stok Miktarı", color="blue")
ax2.tick_params(axis='y', labelcolor="blue")

lines_1, labels_1 = ax1.get_legend_handles_labels()
lines_2, labels_2 = ax2.get_legend_handles_labels()
ax1.legend(lines_1 + lines_2, labels_1 + labels_2, loc="upper left")

plt.title("ABC Kategorilerine Göre Karlılık ve Stok Yönetimi Analizi")
plt.show()
No description has been provided for this image
In [20]:
a_zarar = df[(df["ABC Category"] == "A") & (df["Profit"] < 0)]
zararli_urunler = a_zarar.groupby("Product Name")[["Sales", "Profit"]].sum().sort_values(by="Profit").reset_index()
In [21]:
top_zarar = zararli_urunler.head(10)

plt.figure(figsize=(10, 6))
sns.barplot(x="Profit", y="Product Name", data=top_zarar, palette="Reds_r")
plt.title("A Kategorisinde En Fazla Zarar Ettiren 10 Ürün")
plt.xlabel("Toplam Zarar ($)")
plt.ylabel("Ürün Adı")
plt.tight_layout()
plt.show()
No description has been provided for this image
In [22]:
abc_kar = df.groupby("ABC Category").agg({
    "Profit": "sum",
    "Sales": "sum"
}).reset_index()

abc_kar["Ortalama Kâr Marjı (%)"] = (abc_kar["Profit"] / abc_kar["Sales"]) * 100
abc_kar = abc_kar.sort_values(by="ABC Category")  
In [23]:
plt.figure(figsize=(8, 5))
sns.barplot(x="ABC Category", y="Profit", data=abc_kar, palette="Blues_d")
plt.title("ABC Kategorilerine Göre Toplam Kâr")
plt.xlabel("ABC Kategorisi")
plt.ylabel("Toplam Kâr ($)")
plt.tight_layout()
plt.show()
No description has been provided for this image
In [24]:
plt.figure(figsize=(8, 5))
sns.barplot(x="ABC Category", y="Ortalama Kâr Marjı (%)", data=abc_kar, palette="coolwarm")
plt.title("ABC Kategorilerine Göre Ortalama Kâr Marjı")
plt.xlabel("ABC Kategorisi")
plt.ylabel("Kâr Marjı (%)")
plt.tight_layout()
plt.show()
No description has been provided for this image

🔍 Analiz Sonuçları ve Gözlemler

  • ABC analizi sonucunda, ürünlerin büyük bir kısmının C kategorisinde yer aldığı, buna karşın satışların ağırlıklı olarak A kategorisindeki sınırlı sayıdaki üründen geldiği görülmüştür. Bu durum, az sayıda ürünün portföye yüksek katkı sağladığını ortaya koymaktadır.

  • Satış dağılımına bakıldığında, A kategorisinin toplam satışların büyük kısmını oluşturduğu, B ve C kategorilerinin ise satışa daha az katkı sağladığı anlaşılmıştır. Bu veriler, satış odaklı kaynak kullanımının A grubuna yöneltilmesi gerektiğine işaret etmektedir.

  • Stok miktarı açısından değerlendirildiğinde, en yüksek stokun C kategorisinde yer aldığı görülmektedir. Bu durum, düşük katkı sağlayan ürünlerin stoklarda fazlaca yer kapladığını ve stok yönetiminin iyileştirilmesi gerektiğini göstermektedir.

  • Kârlılık ve stok ilişkisi incelendiğinde, A kategorisinin düşük stok miktarına rağmen yüksek kâr sağladığı; buna karşılık C kategorisinin yüksek stokla düşük kârlılık getirdiği tespit edilmiştir. Bu durum, stokların kârlılık düzeyine göre yeniden dengelenmesi gerektiğini ortaya koymaktadır.

  • A kategorisinde yer almasına rağmen zarar eden bazı ürünler belirlenmiştir. Bu ürünlerin gözden geçirilmesi, gerekirse fiyatlandırma ve ürün stratejilerinin yeniden ele alınması gerekmektedir.

  • Genel olarak, A kategorisi hem toplam kâr hem de ortalama kâr marjı açısından en güçlü grup olarak öne çıkmıştır. C kategorisi ise düşük kârlılık ve yüksek stok oranı ile daha fazla maliyet yaratan bir yapıya sahiptir.


⏱️ Zaman Bazlı Performans Analizi¶


Amaç:¶

Bu analiz, perakende satış ve kârlılık performansının zaman içerisindeki değişimini inceleyerek dönemsel eğilimleri ortaya koymayı amaçlamaktadır. Aylık bazda yapılan bu değerlendirme ile hem toplam satış ve kâr hareketleri hem de segmentler, ürün kategorileri ve bölgeler özelinde oluşan trendler analiz edilmiştir. Bu sayede sezonluk etkiler, kampanya dönemleri ve performans sapmaları tespit edilerek, ürün portföyü yönetimi, stok planlaması ve pazarlama stratejilerine yönelik veri temelli kararlar desteklenmiştir.

Uygulanan Analizler¶

  • Aylık bazda toplam satış ve toplam kâr trend analizi
  • Satış & kâra göre oluşturulan segmentlerin zaman içindeki performanslarının karşılaştırılması
  • Üç ana ürün kategorisinin (Furniture, Office Supplies, Technology) dönemsel satış değişimlerinin izlenmesi
  • Bölgesel bazda (Central, East, South, West) aylık satış ve kâr dağılımlarının analizi yapılmıştır.
In [25]:
df['Order Date'] = pd.to_datetime(df['Order Date'])
monthly_perf = df.groupby(df['Order Date'].dt.to_period("M")).agg({
    'Sales': 'sum',
    'Profit': 'sum'
}).reset_index()
monthly_perf['Order Date'] = monthly_perf['Order Date'].astype(str)
plt.figure(figsize=(14,6))
sns.lineplot(data=monthly_perf, x='Order Date', y='Sales', label='Satış')
sns.lineplot(data=monthly_perf, x='Order Date', y='Profit', label='Kâr')
plt.title('Aylık Satış ve Kâr Trendleri')
plt.xticks(rotation=45)
plt.grid(True)
plt.tight_layout()
plt.show()
No description has been provided for this image
In [26]:
df['Order Date'] = pd.to_datetime(df['Order Date'])
df['Order Month'] = df['Order Date'].dt.to_period('M').astype(str)

category_perf = df.groupby(['Product Category', 'Product Sub-Category']).agg({
    'Sales': 'sum',
    'Profit': 'sum'
}).reset_index()


category_perf['Profit Margin (%)'] = (category_perf['Profit'] / category_perf['Sales']) * 100

sales_median = category_perf['Sales'].median()
profit_margin_median = category_perf['Profit Margin (%)'].median()

def segment_category(row):
    if row['Sales'] >= sales_median and row['Profit Margin (%)'] >= profit_margin_median:
        return "Yüksek Satış - Yüksek Kâr"
    elif row['Sales'] >= sales_median and row['Profit Margin (%)'] < profit_margin_median:
        return "Yüksek Satış - Zarar"
    elif row['Sales'] < sales_median and row['Profit Margin (%)'] >= profit_margin_median:
        return "Düşük Satış - Yüksek Kâr"
    else:
        return "Düşük Satış - Zarar"


category_perf['Segment'] = category_perf.apply(segment_category, axis=1)

df = df.merge(category_perf[['Product Sub-Category', 'Segment']], on='Product Sub-Category', how='left')

monthly_segment = df.groupby(['Order Month', 'Segment']).agg({
    'Sales': 'sum',
    'Profit': 'sum'
}).reset_index()


plt.figure(figsize=(14, 6))
sns.lineplot(data=monthly_segment, x='Order Month', y='Sales', hue='Segment', marker="o")
plt.title("Zaman Bazlı Segment Bazında Satış Trendleri", fontsize=14)
plt.xticks(rotation=45)
plt.xlabel("Sipariş Dönemi")
plt.ylabel("Toplam Satış ($)")
plt.grid(True)
plt.tight_layout()
plt.show()
No description has been provided for this image
In [27]:
categories = df["Product Category"].unique()

plt.figure(figsize=(12,6))

for category in categories:
    category_sales = df[df["Product Category"] == category].groupby(df["Order Date"].dt.to_period("M"))["Sales"].sum()
    category_sales = category_sales.to_timestamp()
    plt.plot(category_sales.index, category_sales, label=category)

plt.xlabel("Tarih")
plt.ylabel("Toplam Satış ($)")
plt.title("Her Ürün Kategorisi İçin Satış Trendleri")
plt.legend()
plt.xticks(rotation=45)
plt.grid(True)
plt.tight_layout()
plt.show()
No description has been provided for this image
In [28]:
df['Order Month'] = df['Order Date'].dt.to_period("M").dt.to_timestamp()
region_month_perf = df.groupby(["Region", "Order Month"]).agg({
    "Sales": "sum",
    "Profit": "sum"
}).reset_index()

plt.figure(figsize=(14, 6))
sns.lineplot(data=region_month_perf, x="Order Month", y="Sales", hue="Region", marker="o")
plt.title("Aylık Satış Trendleri (Bölgelere Göre)", fontsize=14)
plt.xlabel("Sipariş Ayı")
plt.ylabel("Satış ($)")
plt.xticks(rotation=45)
plt.grid(True)
plt.tight_layout()
plt.show()

# Grafik 2: Aylık Kâr Trendleri (Bölgelere Göre)
plt.figure(figsize=(14, 6))
sns.lineplot(data=region_month_perf, x="Order Month", y="Profit", hue="Region", marker="o")
plt.title("Aylık Kâr Trendleri (Bölgelere Göre)", fontsize=14)
plt.xlabel("Sipariş Ayı")
plt.ylabel("Kâr ($)")
plt.xticks(rotation=45)
plt.grid(True)
plt.tight_layout()
plt.show()
No description has been provided for this image
No description has been provided for this image

🔍 Analiz Sonuçları ve Gözlemler

  • Nisan ayında satışlar zirve yaparken, kâr sınırlı kalmıştır.Bu durum, düşük kârlı ürünlerin öne çıktığını ve kampanya etkisinin belirgin olduğunu göstermektedir.

  • “Yüksek Satış - Yüksek Kâr” segmenti özellikle Nisan ayında güçlü performans sergilemiştir. Bu segmentin stratejik olarak desteklenmesi önerilir.

  • Office Supplies kategorisi, dönemsel olarak satış artışı göstermiştir. Diğer ana kategoriler olan Furniture ve Technology ise daha dengeli ve istikrarlı bir seyir izlemiştir.

  • Güney bölgesi (South), hem satış hem de kâr açısından öne çıkmıştır. Bu durum, bölgesel kampanyaların veya stratejik satış yaklaşımlarının etkisini göstermektedir.

  • Bazı bölgelerde yüksek satış hacmine rağmen düşük kârlılık gözlemlenmiştir. Bu farkın, operasyonel maliyetler veya uygulanan promosyon stratejileriyle ilişkili olabileceği düşünülmektedir.

  • Zaman bazlı analiz, dönemsel dalgalanmaların ürün ve bölge performansına etkisini açıkça ortaya koymuş, stratejik planlama için değerli içgörüler sağlamıştır.


📦 Ürün Verimliliği Analizi¶


Amaç:

Bu analizde, ürünlerin sadece satış miktarına göre değil; lojistik ve depolama açısından ne kadar verimli olduğu değerlendirilmiştir.

Her ürün kategorisine ait ürünlerin hacim katsayıları kullanıcı tarafından (volume_map) manuel olarak tanımlanmıştır. Bu katsayılar kullanılarak ürünlerin ne kadar kâr sağladığı ve hangi alanda ne kadar yer kapladığı normalize edilmiştir.

Hedef:

Sınırlı alanda maksimum verimliliği sağlayan ürünleri belirleyerek portföy optimizasyonuna katkıda bulunmaktır.

Uygulanan Analizler:

  • Alan Başına En Yüksek Kâr Sağlayan Ürünler

  • Alan Başına En Yüksek Satış Sağlayan Ürünler

  • Ürün Kategorilerine Göre Alan Başına Kâr Verimliliği

  • Ürün Kategorilerine Göre Alan Başına Satış Verimliliği

⚠️ Not: Bu analizde ürün hacim verileri volume_map sözlüğü üzerinden manuel olarak tanımlanmıştır. Volume bilgisi eksik veya harici kategorilere ait olan ürünler analiz kapsamına dahil edilmemiştir. Sonuçlar yalnızca tanımlı alt kategorilere göre değerlendirilmiştir.

In [29]:
product_perf = df.groupby('Product Name').agg({
    'Sales': 'sum',
    'Profit': 'sum'
}).reset_index()

product_perf['Profit Margin (%)'] = (product_perf['Profit'] / product_perf['Sales']) * 100

product_categories = df[['Product Name', 'Product Category']].drop_duplicates()
product_perf = product_perf.merge(product_categories, on='Product Name', how='left')

volume_map = {
    'Furniture': 3,
    'Technology': 2,
    'Office Supplies': 1
}
product_perf['Volume Unit'] = product_perf['Product Category'].map(volume_map)

product_perf['Profit per Unit Volume'] = product_perf['Profit'] / product_perf['Volume Unit']
product_perf['Sales per Unit Volume'] = product_perf['Sales'] / product_perf['Volume Unit']

from IPython.display import display

print(" Alan Başına En Yüksek Kâr Sağlayan Ürünler:")
display(product_perf.sort_values(by='Profit per Unit Volume', ascending=False).head(10)[
    ['Product Name', 'Product Category', 'Profit', 'Volume Unit', 'Profit per Unit Volume']
])

print(" Alan Başına En Yüksek Satış Sağlayan Ürünler:")
display(product_perf.sort_values(by='Sales per Unit Volume', ascending=False).head(10)[
    ['Product Name', 'Product Category', 'Sales', 'Volume Unit', 'Sales per Unit Volume']
])
 Alan Başına En Yüksek Kâr Sağlayan Ürünler:
Product Name Product Category Profit Volume Unit Profit per Unit Volume
349 Fellowes PB500 Electric Punch Plastic Comb Bin... Office Supplies 23865.9042 1 23865.904200
374 GBC DocuBind TL300 Electric Binding System Office Supplies 11004.4512 1 11004.451200
685 Smead Adjustable Mobile File Trolley with Lock... Office Supplies 9906.6199 1 9906.619900
408 Global Troy™ Executive Leather Low-Back Tilter Furniture 18628.1453 3 6209.381767
480 Ibico Hi-Tech Manual Binding System Office Supplies 5657.5584 1 5657.558400
163 Avery White Multi-Purpose Labels Office Supplies 4905.3024 1 4905.302400
358 Fellowes Super Stor/Drawer® Files Office Supplies 4766.7500 1 4766.750000
481 Ibico Ibimaster 300 Manual Binding System Office Supplies 4568.6073 1 4568.607300
424 Hewlett Packard LaserJet 3310 Copier Technology 8798.1831 2 4399.091550
608 Okidata ML395C Color Dot Matrix Printer Technology 7709.3100 2 3854.655000
 Alan Başına En Yüksek Satış Sağlayan Ürünler:
Product Name Product Category Sales Volume Unit Sales per Unit Volume
349 Fellowes PB500 Electric Punch Plastic Comb Bin... Office Supplies 69013.48 1 69013.480
288 Economy Rollaway Files Office Supplies 35607.28 1 35607.280
523 Lexmark 4227 Plus Dot Matrix Printer Technology 61071.73 2 30535.865
685 Smead Adjustable Mobile File Trolley with Lock... Office Supplies 23995.11 1 23995.110
608 Okidata ML395C Color Dot Matrix Printer Technology 47611.09 2 23805.545
628 Polycom ViewStation™ ISDN Videoconferencing Unit Technology 46538.69 2 23269.345
358 Fellowes Super Stor/Drawer® Files Office Supplies 20478.15 1 20478.150
408 Global Troy™ Executive Leather Low-Back Tilter Furniture 50871.21 3 16957.070
374 GBC DocuBind TL300 Electric Binding System Office Supplies 15948.48 1 15948.480
354 Fellowes Staxonsteel® Drawer Files Office Supplies 14711.35 1 14711.350
In [30]:
category_volume_perf = product_perf.groupby("Product Category").agg({
    "Profit per Unit Volume": "mean",
    "Sales per Unit Volume": "mean"
}).reset_index()

display(category_volume_perf)
Product Category Profit per Unit Volume Sales per Unit Volume
0 Furniture 91.695421 1147.368056
1 Office Supplies 176.525863 1075.696810
2 Technology 174.312862 1648.761458
In [31]:
plt.bar(category_volume_perf['Product Category'], category_volume_perf['Profit per Unit Volume'], color='orange')
plt.title('Ürün Kategorilerine Göre Alan Başına Kâr Verimliliği')
plt.xlabel('Ürün Kategorisi')
plt.ylabel('Kâr / Hacim')
plt.grid(True)
plt.tight_layout()
plt.show()

plt.figure(figsize=(10, 5))
plt.bar(category_volume_perf['Product Category'], category_volume_perf['Sales per Unit Volume'], color='skyblue')
plt.title('Ürün Kategorilerine Göre Alan Başına Satış Verimliliği')
plt.xlabel('Ürün Kategorisi')
plt.ylabel('Satış / Hacim')
plt.grid(True)
plt.tight_layout()
plt.show()
No description has been provided for this image
No description has been provided for this image

📊 Analiz Sonuçları ve Gözlemler

• Technology kategorisi, hem satış hem de kârlılık verimliliği açısından en yüksek performansı göstermiştir. Alan başına getirisinin yüksekliği, sınırlı depolama alanı olan mağazalarda önceliklendirilmesi gerektiğini ortaya koymaktadır.
• Office Supplies kategorisi ise, satış verimliliğinde iyi performans sergilerken bazı ürünlerde düşük kârlılık dikkat çekmektedir.
• Furniture kategorisi, yüksek hacim kaplamasına rağmen düşük kâr oranıyla verimlilik açısından zayıf kalmaktadır. Stok maliyetlerinin yüksek olabileceği bu kategori için yerleşim ve promosyon stratejileri gözden geçirilmelidir.
• Özellikle “Fellowes PB500 Electric Punch Plastic Comb Bind” gibi ürünler küçük hacimle yüksek kâr sağladığı için örnek verimli ürünler arasında yer almaktadır.


📊 Bölgesel Satış ve Kârlılık Performans Analizi¶


Amaç:¶

Bu analiz kapsamında, satış ve kârlılık verileri coğrafi bölgelere göre detaylandırılarak değerlendirilmiştir. Satış hacmi, toplam kâr, zarar eden ürünlerin dağılımı, sipariş sayıları ve ürün kategorilerine göre performans gibi metrikler bölgesel bazda incelenmiştir. Amaç; bölgesel performans farklarını ortaya koyarak stratejik karar süreçlerine destek olmak, kaynak tahsisini optimize etmek ve yüksek potansiyele sahip bölgeleri belirleyerek satış/kârlılık artırıcı aksiyonlar planlamaktır.

Uygulanan Analizler:

  • Bölgelere göre toplam satış ve kâr analizi

  • Bölgelere göre kategori bazlı satış analizi

  • Zarar eden ürünlerin bölgelere göre dağılımı

  • Bölgelere göre sipariş adedi

  • Eyalet bazında kâr dağılımı

In [32]:
region_perf = df.groupby("Region")[["Sales", "Profit"]].sum().reset_index()

plt.figure(figsize=(10, 6))
plt.plot(region_perf["Region"], region_perf["Sales"], marker='o', label='Satış ($)', linestyle='-', color='blue')
plt.plot(region_perf["Region"], region_perf["Profit"], marker='o', label='Kâr ($)', linestyle='--', color='orange')

plt.title("Bölgelere Göre Satış ve Kâr (Çizgi Grafik)")
plt.xlabel("Bölge")
plt.ylabel("Tutar ($)")
plt.grid(True, linestyle='--', alpha=0.5)
plt.legend()
plt.tight_layout()
plt.show()
No description has been provided for this image
In [33]:
region_category_perf = df.groupby(["Region", "Product Category"])["Sales"].sum().unstack()

pastel_colors = sns.color_palette("pastel")

region_category_perf.plot(kind="bar", figsize=(12, 6), color=pastel_colors)

plt.title("Bölgelere Göre Kategori Bazlı Satışlar")
plt.xlabel("Bölge")
plt.ylabel("Toplam Satış ($)")
plt.xticks(rotation=0)
plt.legend(title="Ürün Kategorisi")
plt.tight_layout()
plt.grid(True)
plt.show()
No description has been provided for this image
In [34]:
loss_by_region = df[df["Profit"] < 0].groupby("Region")["Profit"].sum()

loss_by_region.plot(kind="bar", color="red", figsize=(10,5))
plt.title("Zarar Eden Ürünlerin Bölgelere Göre Dağılımı")
plt.xlabel("Bölge")
plt.ylabel("Toplam Zarar ($)")
plt.grid(True)
plt.tight_layout()
plt.show()
No description has been provided for this image
In [35]:
order_count_by_region = df.groupby("Region")["Order ID"].nunique()

order_count_by_region.plot(kind="barh", color="darkblue", figsize=(10,5))
plt.title("Bölgelere Göre Sipariş Sayısı")
plt.xlabel("Sipariş Adedi")
plt.ylabel("Bölge")
plt.tight_layout()
plt.show()
No description has been provided for this image
In [36]:
state_profit = df.groupby("State or Province")["Profit"].sum().reset_index()

state_abbrev = {
    'Alabama': 'AL', 'Alaska': 'AK', 'Arizona': 'AZ', 'Arkansas': 'AR',
    'California': 'CA', 'Colorado': 'CO', 'Connecticut': 'CT', 'Delaware': 'DE',
    'Florida': 'FL', 'Georgia': 'GA', 'Hawaii': 'HI', 'Idaho': 'ID',
    'Illinois': 'IL', 'Indiana': 'IN', 'Iowa': 'IA', 'Kansas': 'KS',
    'Kentucky': 'KY', 'Louisiana': 'LA', 'Maine': 'ME', 'Maryland': 'MD',
    'Massachusetts': 'MA', 'Michigan': 'MI', 'Minnesota': 'MN', 'Mississippi': 'MS',
    'Missouri': 'MO', 'Montana': 'MT', 'Nebraska': 'NE', 'Nevada': 'NV',
    'New Hampshire': 'NH', 'New Jersey': 'NJ', 'New Mexico': 'NM', 'New York': 'NY',
    'North Carolina': 'NC', 'North Dakota': 'ND', 'Ohio': 'OH', 'Oklahoma': 'OK',
    'Oregon': 'OR', 'Pennsylvania': 'PA', 'Rhode Island': 'RI', 'South Carolina': 'SC',
    'South Dakota': 'SD', 'Tennessee': 'TN', 'Texas': 'TX', 'Utah': 'UT',
    'Vermont': 'VT', 'Virginia': 'VA', 'Washington': 'WA', 'West Virginia': 'WV',
    'Wisconsin': 'WI', 'Wyoming': 'WY'
}

state_profit["State Code"] = state_profit["State or Province"].map(state_abbrev)
In [37]:
import plotly.express as px

fig = px.choropleth(
    state_profit,
    locations="State Code",  
    locationmode="USA-states",
    color="Profit",
    scope="usa",
    color_continuous_scale="RdBu",
    title="Eyalet Bazlı Kâr Dağılımı (ABD Haritası)"
)


fig.update_layout(
    geo=dict(bgcolor='rgba(0,0,0,0)'),
    height=600,  
    width=1000   
)   

fig.show()

🔍 Analiz Sonuçları ve Gözlemler

• East ve West bölgeleri, satış hacmi açısından yüksek performans sergilemiştir.

• South bölgesi, hem satış hem de kârlılık bakımından zayıf performansa sahiptir. Bu durum, bölgeye özgü stratejilerin gözden geçirilmesi gerektiğini göstermektedir.

• Office Supplies kategorisi bazı bölgelerde zarar yazarken, Technology kategorisi genel olarak daha yüksek kâr sağlamıştır.

• Sipariş sayısı yüksek olan bölgeler her zaman yüksek kârlılık getirmemektedir. Ürün kâr marjı, indirim oranları ve kampanya politikalarının ayrıca değerlendirilmesi gerekmektedir.

• Harita analizi sonucunda, Virginia (VA) eyaletinin en yüksek kârı sağladığı, Texas (TX) eyaletinin ise zarar ettiği görülmektedir.Bu durum, eyalet bazlı performansın detaylı şekilde ele alınmasının önemini göstermektedir.

In [ ]: